#include "xtypes.h"
#include "util_sync.h"
#include "xmemory.h"



#ifndef _WIN32_WINNT		
#define _WIN32_WINNT 0x0501
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>





void CxCriticalSection::Enter()
{
	if( m_pCriticalSection != NULL )
	{
		::EnterCriticalSection((CRITICAL_SECTION*)m_pCriticalSection);
	}	
}

void CxCriticalSection::Leave()
{
	if( m_pCriticalSection != NULL )
	{
		::LeaveCriticalSection((CRITICAL_SECTION*)m_pCriticalSection);
	}	
}

bool_t CxCriticalSection::TryEnter()
{
	BOOL r = TryEnterCriticalSection( (CRITICAL_SECTION*)m_pCriticalSection);
	return r ? TRUE:FALSE;
}


CxCriticalSection * CxCriticalSection::Create()
{
	CxCriticalSection * _Ptr = xNewObject<CxCriticalSection>();
	if(_Ptr==NULL)
		return NULL;

	return _Ptr;
}

void CxCriticalSection::Release()
{
	xDeleteObject<CxCriticalSection>(this);
}

CxCriticalSection::CxCriticalSection()
{
	_Init();
	_Alloc();
}

CxCriticalSection::~CxCriticalSection()
{
	_Tidy();
}


CxCriticalSection::CxCriticalSection( const CxCriticalSection & _Ref )
{
	_Init();
	_Copy( _Ref );
}
CxCriticalSection & CxCriticalSection::operator=( const CxCriticalSection & _Ref )
{
	_Copy( _Ref );
	return *this;
}

void CxCriticalSection::_Init()
{
	m_pCriticalSection = NULL;
}

void CxCriticalSection::_Alloc()
{
	m_pCriticalSection = (wildptr_t)xMemoryAlloc( sizeof(CRITICAL_SECTION) );
	if( m_pCriticalSection != NULL )
	{
		::InitializeCriticalSection((CRITICAL_SECTION*)m_pCriticalSection);
	}
}

void CxCriticalSection::_Tidy()
{
	if(m_pCriticalSection!=NULL)
	{
		DeleteCriticalSection((CRITICAL_SECTION*)m_pCriticalSection);

		xMemoryFree(m_pCriticalSection);
		m_pCriticalSection = NULL;
	}
}

void CxCriticalSection::_Copy( const CxCriticalSection & _Ref )
{
	_Tidy();
	_Alloc();
}







void CxSyncEvent::Wait( uint_t _Ms )
{
	::WaitForSingleObject((HANDLE)m_hEvent, _Ms);
}

void CxSyncEvent::Set()
{
	::SetEvent((HANDLE)m_hEvent);
}

void CxSyncEvent::Reset()
{
	::ResetEvent((HANDLE)m_hEvent);
}

void CxSyncEvent::Pulse()
{
	::PulseEvent((HANDLE)m_hEvent);
}

bool_t CxSyncEvent::IsSeted() const
{
	if( m_hEvent == NULL )return false;
	return (WaitForSingleObject( (HANDLE)m_hEvent, 0 ) != WAIT_TIMEOUT);
}


CxSyncEvent * CxSyncEvent::Create()
{
	CxSyncEvent * _Ptr = xNewObject<CxSyncEvent>();
	if(_Ptr==NULL)
		return NULL;

	return _Ptr;
}

void CxSyncEvent::Release()
{
	xDeleteObject<CxSyncEvent>(this);
}



CxSyncEvent::CxSyncEvent()
{
	_Init();
	_Alloc();
}

CxSyncEvent::~CxSyncEvent()
{
	_Tidy();
}

void CxSyncEvent::_Init()
{
	m_hEvent = 0;
}

void CxSyncEvent::_Alloc()
{
	_Tidy();

	m_hEvent = (uint_t)CreateEvent(NULL, TRUE, FALSE, NULL);
}

void CxSyncEvent::_Tidy()
{
	if(m_hEvent!=0)
	{
		::CloseHandle((HANDLE)m_hEvent);
		m_hEvent = 0;
	}
}


